﻿/*  PCi Battery Bench Tool - Web / Video battery life measurement with MPC HC & IE
    Copyright © 2011, LEGRAND David
    Mail : david@pcinpact.com

    http://forum.pcinpact.com/topic/154156-pci-tool-battery-benchmark-suite/
    http://code.google.com/p/pci-bbs/

    This file is part of PCi Battery Bench Tool.

    PCi Battery Bench Tool is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PCi Battery Bench Tool is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PCi Battery Bench Tool.  If not, see <http://www.gnu.org/licenses/>. 
 
    You're not allowed to use PC INpact name or logo without permission */

using System;
using System.Diagnostics;
using Microsoft.Win32;

namespace PCi_Battery_Bench_Tool
{
    class Program
    {
        // On définit les variables qui seront utiles pour le timer
        static System.Timers.Timer t;
        static int i = 0;
        static int interval = 60;

        // On définit les textes utiles sur l'ensemble de l'application
        static string press_key = " Press key to continue...";
        static string no_conf = " Conf file not found. It will be created.";
        static string log_file = "log.txt";

        static void Main(string[] args)
        {
            // On donne le nom de l'application à la console 
            string app_name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
            Console.Title = app_name;

            // On définit les variables qui seront utiles
            string urls_file = "urls.txt";
            string config_file = "config.ini";

            string mpchc_url = @"http://mpc-hc.sourceforge.net/download-media-player-classic-hc.html";
            string adobe_url = @"http://www.adobe.com/go/EN_US-H-GET-FLASH";

            string mpchc_args = " /play /fullscreen";

            string no_flash = " It seems that Flash is not installed.";
            string no_video = " Video file not found.";
            string no_urls = " " + urls_file + "not found. It will be created.";
            string no_urls_2 = " Please indicate URLs you want to browse during the test.";
            string no_mpchc = " MPC HC not found in the indicated folder.";
            string no_mpchc_2 = " Download it and launch the test again.";

            string warn_loop = "WARNING : Please enable infinite loop reading in MPC HC";
            string warn_IE = "WARNING : Internet Explorer will be closed";
            string error_test = " Error during test, application will stop.";

            string[] usage = { " " + app_name + " (c) 2011 - LEGRAND David - PC INpact.com",
                               "\n",
                               " You indicated no arguments.",
                               " Usage : " + app_name + ".exe <mode> <options>",
                               "\n",
                               " log          : just log elapsed time.",
                               " video <file> : play video file with MPC HC.",
                               " web <time>   : browse URLs in " + urls_file + " during indicated time (in seconds)." };

            // La clef de registre qui servira à lire la veresion de Flash
            RegistryKey RK = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Macromedia\FlashPlayer");

            // S'il n'y a pas assez d'arguments d'indiqué
            if (args.Length < 1)
            {
                Aff_Message(usage);
            }
            // Si l'on a assez d'arguments indiqués
            else
            {
                switch (args[0])
                {
                    // Si l'on a demandé un simple log
                    case "log":

                        // On lance le timer
                        Launch_Timer();

                        // On place un ReadLine pour éviter que l'application ne ferme.
                        Console.ReadLine();

                        break;

                    // Si l'on a demandé un test web
                    case "web":

                        // Si le fichier d'URLs n'existe pas
                        if (!System.IO.File.Exists(urls_file))
                        {
                            // On affiche un message d'erreur
                            Aff_Message(new string[2] { no_urls, no_urls_2 });

                            // On créé un fichier vide et on l'ouvre
                            System.IO.File.Create(urls_file);
                            Process.Start("notepad.exe", urls_file);
                        }

                        // Si Flash n'a pas été trouvé
                        else if (RK == null)
                        {
                            Aff_Message(new string[1] { no_flash });
                            Process.Start(adobe_url);
                        }

                        // Si tout est OK
                        else
                        {
                            // On affiche la version de Flash relevée, et l'on remplace les ',' par des '.' pour la mise en forme
                            Aff_Message(new string[1] { " Flash version : " + RK.GetValue("CurrentVersion").ToString().Replace(',', '.') });

                            // On affiche un avertissement avec une pause de 10 secondes
                            Warning_message(warn_IE, 10);

                            // On lance le timer qui sert au relevé de résultat
                            Launch_Timer();

                            // On initialise les variables utiles
                            int timing = int.Parse(args[1]);
                            string[] urls = System.IO.File.ReadAllLines(urls_file);

                            // On utilise un try / catch pour la gestion des erreurs
                            try
                            {
                                // On effectue le traitement des URL en boucle
                                while (true)
                                {
                                    URL_Reader(timing, urls);
                                }
                            }
                            catch { Aff_Message(new string[1] { error_test }); }
                        }

                        break;

                    // Si l'on a demandé un test vidéo
                    case "video":

                        // On récupère le nom de la vidéo à lire
                        string video = args[1];

                        // Si MPC HC n'existe pas
                        if (!System.IO.File.Exists(get_mpchc_path(config_file)))
                        {
                            // On affiche un message et on va sur le site du logiciel
                            Aff_Message(new string[2] { no_mpchc, no_mpchc_2 });
                            Process.Start(mpchc_url);
                        }

                        // Si le fichier vidéo demandé n'existe pas
                        else if (!System.IO.File.Exists(video))
                        {
                            // On affiche un message d'erreur
                            Aff_Message(new string[1] { no_video });
                        }

                        // Si tout est OK
                        else
                        {
                            // On affiche un avertissement avec une pause de 5 secondes
                            Warning_message(warn_loop, 5);

                            // On lance le timer qui sert à connaître le résultat
                            Launch_Timer();

                            // On lit la vidéo
                            try
                            {
                                System.Diagnostics.Process.Start(get_mpchc_path(config_file), video + mpchc_args);
                            }
                            catch { Console.WriteLine(error_test); }

                            // On place un ReadLine pour éviter que l'application ne ferme.
                            Console.ReadLine();
                        }

                        break;
                }
            }
        }

        // Fonction qui affiche un message d'erreur avec une pause depuis un texte
        private static void Warning_message(string warn_loop, int seconds)
        {
            // On effecture la mise en forme du message d'erreur que l'on affiche
            Console.WriteLine();
            Console.Write(" ");
            Console.WriteLine(new string('*', warn_loop.Length + 4));
            Console.WriteLine(" * " + new string(' ', warn_loop.Length) + " *");
            Console.WriteLine(" * " + warn_loop + " *");
            Console.WriteLine(" * " + new string(' ', warn_loop.Length) + " *");
            Console.Write(" ");
            Console.WriteLine(new string('*', warn_loop.Length + 4));
            Console.WriteLine();

            // On fait une pause de quelques secondes
            System.Threading.Thread.Sleep(seconds * 1000);
        }

        // Fonction qui affiche un message depuis un tableau de string et attend l'appui d'une touche
        private static void Aff_Message(string[] messages)
        {
            Console.WriteLine();
            foreach (string message in messages)
            {
                Console.WriteLine(message);
            }
            Console.WriteLine();
            Console.Write(press_key);
            Console.ReadKey();
        }

        // Fonction qui parcourt une liste d'URLS et visite les sites en fonction d'un timing indiqué en secondes
        private static void URL_Reader(int timing, string[] urls)
        {
            // Pour chaque URL dans le fichier
            foreach (string url in urls)
            {
                // On établit la liste des processus afin de tuer ceux de l'explorateur
                foreach (Process clsProcess in Process.GetProcesses())
                {
                    if (clsProcess.ProcessName.Contains("iexplore")) clsProcess.Kill();
                }

                // On lance le navigateur, et on attend quelques secondes
                System.Diagnostics.Process.Start("iexplore.exe", url);
                System.Threading.Thread.Sleep(timing * 1000);

            }
        }

        // La fonction qui lance le timer
        private static void Launch_Timer()
        {
            Console.Clear();
            Console.Write(Environment.NewLine + " 0 minute");
            t = new System.Timers.Timer();
            t.AutoReset = true;
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Interval = interval * 1000;
            t.Start();
        }

        // Fonction qui récupère le path complet de MPC HC depuis le fichier de config indiqué
        static string get_mpchc_path(string config_file)
        {
            string path = "";

            if (System.IO.File.Exists(config_file))
            {
                string[] config = System.IO.File.ReadAllLines(config_file);

                path = config[0].Split('=')[1].Trim();
                if (!path.EndsWith("\\")) path += "\\";
                path += config[1].Split('=')[1].Trim();
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine(no_conf);
                Console.WriteLine();
                Console.Write(press_key);
                Console.ReadLine();

                string[] config_defaut = { "path=", "exe=" };
                System.IO.File.WriteAllLines(config_file, config_defaut);
                Process.Start("notepad.exe", config_file);

                Environment.Exit(-1);
            }
            return path;
        }

        // La fonction qui effectue le log et affiche le résultat
        static void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            i += 1;

            // On gère le cas du pluriel
            string min_text = String.Format("{0} minute{1}", i, i > 1 ? "s" : "");

            // On affiche le texte et on écrit dans le fichier de log.
            Console.Write("\r " + min_text);
            System.IO.File.WriteAllText(log_file, min_text);
        }
    }
}